#include <iostream>
#include <sys/socket.h>    
#include <netinet/in.h>    
#include <unistd.h>       

#include "Common.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"

using namespace LogModule;

namespace SocketMoudel
{
    class Socket
    {
    public:
        virtual ~Socket() {}
        virtual void SocketOrDie() = 0;
        virtual void BindOrDie(uint16_t port) = 0;
        virtual void ListenOrDie(int backlog) = 0;

        
    };


    const static int defaultfd = -1;
    class TCPSocket : public Socket
    {
    public:
        TCPSocket():_socketfd(defaultfd)
        {}
        TCPSocket(int fd):_socketfd(fd)
        {}
        virtual ~TCPSocket(){}

        //创建套接字
        virtual void SocketOrDie()
        {
            _socketfd = socket(AF_INET,SOCK_STREAM,0);
            if(_socketfd < 0)
            {
                LOG(LogLevel::FATAL) << "socket error";
                exit(SOCKET_ERR);
            }
            LOG(LogLevel::INFO) << "socket success";

        }
        //绑定
        virtual void BindOrDie(uint16_t port)
        {
            InetAddr localaddr(port);
            int n = bind(_socketfd,localaddr.NetAddrPtr(),localaddr.AddrLen());
            if(n < 0)
            {
                LOG(LogLevel::FATAL) << "bind error";
                exit(BIND_ERR);
            }
            LOG(LogLevel::INFO) << "bind success";
        }
        //连接
        virtual void ListenOrDie(int backlog)
        {
            int n = listen(_socketfd,10);
            if(n < 0)
            {
                LOG(LogLevel::FATAL) << "listen error";
                exit(LISTEN_ERR);
            }
            LOG(LogLevel::INFO) << "listen success";
        }
    private:
        int _socketfd;
    };
}
